package com.cskaoyan.market.controller;

import com.cskaoyan.market.db.domain.MarketAd;
import com.cskaoyan.market.db.domain.MarketAdmin;
import com.cskaoyan.market.service.AdminService;
import com.cskaoyan.market.service.AdminServiceImpl;
import com.cskaoyan.market.util.JacksonUtil;
import com.cskaoyan.market.util.ResponseUtil;
import com.fasterxml.jackson.annotation.JacksonAnnotation;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName AdminAuthController
 * @Description: TODO
 * /admin/auth/login
 * /admin/auth/logout
 * /admin/auth/info
 * @Author 远志 zhangsong@cskaoyan.onaliyun.com
 * @Date 2024/3/14 10:24
 * @Version V1.0
 **/
@WebServlet("/admin/auth/*")
public class AdminAuthController extends HttpServlet {

    AdminService adminService = new AdminServiceImpl();


    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String requestURI = req.getRequestURI();
        String op = requestURI.replace(req.getContextPath() + "/admin/auth/", "");
        if("info".equals(op)){
            info(req, resp);
        }
    }

    //管理员的个人中心
    private void info(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        //从session域里面获取name、avatar
        HttpSession session = req.getSession();
        MarketAdmin admin = (MarketAdmin) session.getAttribute("admin");
        Map<String, Object> data = new HashMap<>();
        //下面两行设置是关于权限相关的，项目二去实现，项目一暂时这么去写，让接口通过即可
        data.put("roles", Arrays.asList("超级管理员"));
        data.put("perms", Arrays.asList("*"));
        data.put("name", admin.getUsername());
        data.put("avatar", admin.getAvatar());
        Object ok = ResponseUtil.ok(data);
        resp.getWriter().println(JacksonUtil.writeValueAsString(ok));
    }

    //登录的逻辑：接收获取用户的参数信息，到系统中进行比对校验，返回特定的结果（参考39.101xxx:8083返回值）
    private void login(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        //参数在哪？请求体中的json字符串
        //2.如何获取参数？可以使用request.getParameter吗？不可以，因为不是key=value&key=value类型
        ServletInputStream inputStream = req.getInputStream();
        //构造一个输出流 ByteArrayOutputStream 把数据写出到数组中
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] bytes = new byte[1024];
        int length = 0;
        while ((length = inputStream.read(bytes)) != -1){
            byteArrayOutputStream.write(bytes, 0, length);
        }
        //得到了位于请求体里面的json字符串
        String requestBody = byteArrayOutputStream.toString("utf-8");
        byteArrayOutputStream.close();
        //把获取到的json字符串转换成可以解析的形式：1，转换成java对象
        String username = JacksonUtil.parseString(requestBody, "username");
        String password = JacksonUtil.parseString(requestBody, "password");
        if(StringUtils.isEmpty(username) || StringUtils.isEmpty(password)){
            //参数为空不合法 但是前后端分离对接的情况下，不可以简单粗暴的返回response.getWriter().println(xxx)
            //我们后端返回的数据 json字符串会被前端的程序解析，渲染在页面上
            Object o = ResponseUtil.badArgument();
            resp.getWriter().println(JacksonUtil.writeValueAsString(o));
            return;
        }
        //在mvc里面叫做调用模型，在三层架构中是调用service
        //mvc和三层架构的关系？符合MVC的不一定是三层架构，但是符合三层架构的一定是属于mvc
        MarketAdmin admin = adminService.login(username, password);
        if(admin == null){
            Object o = ResponseUtil.wrongUsernameOrPassword();
            //无需自己去new oBjectMapper
            String s = JacksonUtil.writeValueAsString(o);
            resp.getWriter().println(s);
            //登录失败，用户名、密码错误 {"errno":605,"errmsg":"用户帐号或密码不正确"}
        }else{
            //用户名、密码匹配
            //登录成功，往session域里面存入数据
            HttpSession session = req.getSession();
            session.setAttribute("admin", admin);
            Map<String,Object> data = new HashMap<>();

            Map<String,String> info = new HashMap<>();
            info.put("nickName", admin.getUsername());
            info.put("avatar", admin.getAvatar());
            data.put("adminInfo", info);
            //token实际上在没有传递cookie时，充当的是会话的凭证，但是项目一修改了部分代码，实际上会携带cookie，所以这个属性可以先随意设置
            //实际上，此处token并没有什么实际的意义，这里面只是为了让这个接口可以通过
            //在真实的项目中，前后端分离的情况下，不会携带cookie，所以需要另外想办法解决会话问题，但是我们对代码进行了修改，所以此处可以不用理会
            data.put("token", session.getId());
            //返回的是一个map，里面包含errno、errmsg、data
            Object ok = ResponseUtil.ok(data);
            //将其转换成json字符串，放置在响应体中
            resp.getWriter().println(JacksonUtil.writeValueAsString(ok));

        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String requestURI = req.getRequestURI();
        String op = requestURI.replace(req.getContextPath() + "/admin/auth/", "");
        if("login".equals(op)){
            login(req, resp);
        }
    }
}
